home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / COMPILER / SATHER / !Sather / Library / Containrs / sa / llist < prev    next >
Text File  |  1996-07-18  |  8KB  |  274 lines

  1. ---------------------------> Sather 1.1 source file <--------------------------
  2. -- Author: Holger Klawitter <holger@ICSI.Berkeley.EDU>
  3. -- Copyright (C) 1995, International Computer Science Institute
  4. -- $Id: llist.sa,v 1.4 1996/07/18 01:00:29 davids Exp $
  5. --
  6. -- LLIST{T} a single connected list containing elements of type T.
  7. -- LL_NODE{T} helper class for LLIST{T}
  8. --
  9. -- COPYRIGHT NOTICE: This code is provided WITHOUT ANY WARRANTY
  10. -- and is subject to the terms of the SATHER LIBRARY GENERAL PUBLIC
  11. -- LICENSE contained in the file: Sather/Doc/License of the
  12. -- Sather distribution. The license is also available from ICSI,
  13. -- 1947 Center St., Suite 600, Berkeley CA 94704, USA.
  14. -------------------------------------------------------------------
  15. class LLIST{T} is
  16.    -- An implemenation of a linked list.  
  17.    -- The list has a build in "position" which can be advanced by calling
  18.    -- "advance" and reset to the first element by calling "rewind"
  19.    -- Elements can be inserted and deleted after the current position
  20.    -- using "insert_after", "insert_before"
  21.    -- Elements may also be inserted at the head of the list by calling 
  22.    -- "insert_head"
  23.    -- Elements may be deleted by calling "delete" which deletes the current
  24.    -- object and advances to the next item
  25.    -- This list can be read with elt!.
  26.    
  27.    -- Implementation:
  28.    -- The linked list uses a header object (LLIST) to avoid
  29.    -- hassles with empty lists.
  30.    -- Data is stored in links, which are LL_NODE{T}s which hold pointers
  31.    -- to the data and the next element. LL_NODEs are not given out by
  32.    -- this class.
  33.  
  34.     ---------- ATTRIBUTES
  35.  
  36.     readonly attr size: INT;
  37.         -- Returns the number of elements stored in the list.
  38.  
  39.     private attr first,prev,cur,last: LL_NODE{T};
  40.  
  41.     ---------- CONSTRUCTION
  42.  
  43.     create: SAME is
  44.         -- Returns a new linked list.
  45.         return new;
  46.     end;
  47.  
  48.     ---------- PREDICATES
  49.  
  50.     is_empty: BOOL
  51.         -- Returns 'true' if empty.
  52.         pre ~void(self)
  53.     is
  54.         return size = 0
  55.     end;
  56.  
  57.     at_last: BOOL
  58.         -- Returns true, if the current element is the last element.
  59.         pre ~void(self) and ~is_empty
  60.     is
  61.         return last = cur
  62.     end;
  63.  
  64.     at_end: BOOL
  65.         -- Returns 'true' if the list is empty or the last
  66.         -- next reached the end of the list.
  67.         pre ~void(self)
  68.     is
  69.         return void(cur)
  70.     end;
  71.  
  72.     ---------- TRAVERSING
  73.  
  74.     rewind
  75.         -- Sets the current position to the first element;
  76.         pre ~void(self)
  77.     is
  78.         cur := first;
  79.         prev := void
  80.     end;
  81.  
  82.     current: T
  83.         -- Returns the current element. Not allowed when
  84.         -- at_end is true or list is empty.
  85.         pre ~void(self) and ~is_empty and ~at_end
  86.     is
  87.         return cur.data
  88.     end;
  89.  
  90.     advance
  91.         -- Advances the current position.
  92.         pre ~void(self) and ~is_empty and ~at_end
  93.     is
  94.         prev := cur;
  95.         cur := cur.next;
  96.     end;
  97.  
  98.     elt!: T
  99.         -- Yields all elements stored in the list in order.
  100.         -- Is re-entrant.
  101.         pre ~void(self)
  102.     is
  103.         c ::= first;
  104.         loop
  105.             until!(void(c));
  106.             yield c.data;
  107.             c := c.next
  108.         end
  109.     end;
  110.  
  111.     ---------- INSERTING
  112.  
  113.     insert_after(t:T)
  114.         -- Inserts the item t after the current element.
  115.         -- Does not change current.
  116.         pre ~void(self) and ~is_empty and ~at_end
  117.     is
  118.         if void(cur.next) then
  119.             assert cur = last;
  120.             last := #LL_NODE{T}(t,void);
  121.             cur.next := last;
  122.         else 
  123.             cur.next := #LL_NODE{T}(t,cur.next);
  124.         end;
  125.         size := size + 1
  126.     end;
  127.  
  128.     insert_before(t:T)
  129.         -- Inserts the item t before the current element.
  130.         -- Does not change current.
  131.         -- This is allowed even if at_end is 'true'.
  132.         pre ~void(self)
  133.     is
  134.         if is_empty then
  135.             first := #LL_NODE{T}(t,void);
  136.             last := first;
  137.             prev := first;
  138.             -- cur := void; -- is done!
  139.         elsif void(prev) then
  140.             assert first = cur;
  141.             first := #LL_NODE{T}(t,cur);
  142.             prev := first;
  143.         else
  144.             prev.next := #LL_NODE{T}(t,cur);
  145.             prev := prev.next;
  146.         end;
  147.         if void(cur) then
  148.             last := prev;
  149.         end;
  150.         size := size + 1;
  151.     end;
  152.  
  153.     insert_front(t:T)
  154.         -- Insert an element at the beginning of the list.
  155.         pre ~void(self)
  156.     is
  157.         if void(first) then
  158.             assert void(last) and void(cur);
  159.             first := #LL_NODE{T}(t,void);
  160.             last := first;
  161.             cur := first
  162.         else
  163.             first := #LL_NODE{T}(t,first);
  164.             if void(prev) then
  165.                 assert cur = first;
  166.                 prev := first
  167.             end;
  168.         end;
  169.         size := size + 1
  170.     end;
  171.  
  172.     insert_back(t:T)
  173.         -- Insert an element at the end of the list.
  174.         pre ~void(self)
  175.     is
  176.         if void(last) then
  177.             assert void(first);
  178.             last := #LL_NODE{T}(t,void);
  179.             first := last;
  180.             cur := last
  181.         else
  182.             last.next := #LL_NODE{T}(t,void);
  183.             last := last.next;
  184.         end;
  185.         size := size + 1;
  186.     end;
  187.  
  188.     ---------- DELETING
  189.  
  190.     delete
  191.         -- Deletes the current object. Advances to the next
  192.         -- item in the list.
  193.         -- Not allowed when no current object available.
  194.         pre ~void(self) and ~is_empty and ~at_end
  195.     is
  196.         at_last ::= cur = last;
  197.  
  198.         if void(prev) then
  199.             assert first = cur;
  200.             first := cur.next;
  201.             cur := first;
  202.         else
  203.             cur := cur.next;
  204.             prev.next := cur;
  205.         end;
  206.         if at_last then
  207.             last := prev;
  208.         end;
  209.         size := size - 1;
  210.     end;
  211.  
  212.     delete_all
  213.         -- Deletes all elements from the list.
  214.         pre ~void(self)
  215.         post is_empty and at_end
  216.     is
  217.         first := void;
  218.         cur := void;
  219.         last := void;
  220.         prev := void;
  221.         size := 0;
  222.     end;
  223.  
  224.     ---------- DEBUGGING
  225.  
  226.     dbg_state: STR
  227.     is
  228.         if void(self) then return "self=void" end;
  229.         count ::= 0;
  230.         loop dummy ::= elt!; count := count + 1 end;
  231.         if size /= count then return "size/=count" end;
  232.         
  233.         if ~void(prev) then
  234.             if prev.next /= cur then return "prev.next/=cur"
  235.             elsif void(last) then return "last=void"
  236.             elsif ~void(last.next) then return "last.next/=void"
  237.             elsif void(first) then return "first=void"
  238.             end
  239.         elsif ~void(first) then
  240.             if cur/=first then return "cur/=first"
  241.             elsif void(last) then return "last=void"
  242.             elsif ~void(last.next) then return "last.next/=void"
  243.             end
  244.         else
  245.             if ~void(cur) then return "cur/=void"
  246.             elsif ~void(last) then return "last/=void"
  247.             end
  248.         end;
  249.         return "ok"
  250.     end;
  251.  
  252. end; -- LLIST{T}
  253. ---------------------------------------------------------------------------
  254. class LL_NODE{T} is
  255.    -- Private to LLIST{T}
  256.    -- A node in a linked list which can hold data of type T.
  257.    -- Implementation:
  258.    -- Holds a pointer to the next element and a pointer to the data
  259.    
  260.     attr data: T;
  261.     attr next: SAME;
  262.  
  263.     create(t:T,n:SAME): SAME is
  264.         res ::= new;
  265.         res.data := t;
  266.         res.next := n;
  267.         return res
  268.     end;
  269.  
  270.     is_eq(l:SAME): BOOL is return SYS::ob_eq(self,l) end;
  271.  
  272. end; -- LL_NODE{T}
  273. ---------------------------------------------------------------------------
  274.